/* t_socket.c : test dgnsc socket 
 * Copyright (C) 2009-2010 drangon <drangon.zhou@gmail.com>
 * 2009-05
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <dgnsc/common.h>
#include <dgnsc/socket.h>

#include <stdio.h>

#ifdef _WIN32
#include <windows.h>
#else
#include <string.h>
#include <errno.h>
#endif

int test_tcp();
int test_udp();

int err()
{
#ifdef _WIN32
	return GetLastError();
#else
	return errno;
#endif
}

int main( int argc, char * argv[] )
{
	dgn_init( "socket.log" );

	char ip[32] = {0};
	dgn_sock_host_to_ip( "www.google.com", ip );
	printf( "ip is [%s]\n", ip );

	test_tcp();
	test_udp();

	dgn_fini();

	return 0;
}

int test_tcp()
{
	dgn_sock_t svr, cli1, cli2;
	svr = dgn_sock_tcp_svr( "127.0.0.1", 3122 );
	cli1 = dgn_sock_tcp_connect( "127.0.0.1", 3122, 100 );
	cli2 = dgn_sock_accept( svr, 100 );
	
	char ip[32];
	int port;
	dgn_sock_local_addr( cli1, ip, &port );
	printf( "cli1 local  [%s:%d]\n", ip, port );
	dgn_sock_remote_addr( cli1, ip, &port );
	printf( "cli1 remote [%s:%d]\n", ip, port );
	dgn_sock_local_addr( cli2, ip, &port );
	printf( "cli2 local  [%s:%d]\n", ip, port );
	dgn_sock_remote_addr( cli2, ip, &port );
	printf( "cli2 remote [%s:%d]\n", ip, port );

	char buf[256];
	int len = sizeof( buf );
	int ret;
	memset( buf, 'a', len );
	ret = dgn_sock_send( cli1, buf, len - 10, 100 );
	printf( "cli1 send ret %d\n", ret );
	ret = dgn_sock_recv( cli2, buf, 30, len, 100 );
	printf( "cli2 recv ret %d\n", ret );

	dgn_sock_close( svr );
	dgn_sock_close( cli1 );
	dgn_sock_close( cli2 );

	return 0;
}

int test_udp()
{
	dgn_sock_t cli1, cli2;
	cli1 = dgn_sock_udp( "127.0.0.1", 3311 );
	cli2 = dgn_sock_udp( "127.0.0.1", 3322 );
	
	char ip[32];
	int port;
	dgn_sock_local_addr( cli1, ip, &port );
	printf( "cli1 local  [%s:%d]\n", ip, port );
	dgn_sock_remote_addr( cli1, ip, &port );
	printf( "cli1 remote [%s:%d]\n", ip, port );

	char buf[60 * 1000];
	int len = sizeof( buf );
	int ret;
	memset( buf, 'a', len );

	len = 10;
	ret = dgn_sock_sendto( cli1, buf, len, "127.0.0.1", 3322 );
	printf( "cli1 send ret %d, err %d\n", ret, err() );
	// len = 60 * 1000; // if this is sent, buffer full, next send may failed
	len = 18 * 100;
	ret = dgn_sock_sendto( cli1, buf, len, "127.0.0.1", 3322 );
	printf( "cli1 send ret %d, err %d\n", ret, err() );
	len = 10 * 100;
	ret = dgn_sock_sendto( cli1, buf, len, "127.0.0.1", 3322 );
	printf( "cli1 send ret %d, err %d\n", ret, err() );
	dgn_sock_local_addr( cli1, ip, &port );
	printf( "cli1 local  [%s:%d]\n", ip, port );
	dgn_sock_remote_addr( cli1, ip, &port );
	printf( "cli1 remote [%s:%d]\n", ip, port );

	ip[0] = '\0', port = -1;
	len = 31 * 1000;
	ret = dgn_sock_recvfrom( cli2, buf, len, ip, &port, 100 );
	printf( "cli2 recv ret %d, ip :  [%s:%d], err %d\n", ret, ip, port, err() );
	len = 16 * 100;  // buffer is small, [win] recv failed, and the packet drop
					 // 	[linux] recv ok, and extra bytes erase
	ret = dgn_sock_recvfrom( cli2, buf, len, ip, &port, 100 );
	printf( "cli2 recv ret %d, ip :  [%s:%d], err %d\n", ret, ip, port, err() );
	len = 60 * 1000; // recv 1000, 1800 has been dropped
	ret = dgn_sock_recvfrom( cli2, buf, len, ip, &port, 100 );
	printf( "cli2 recv ret %d, ip :  [%s:%d], err %d\n", ret, ip, port, err() );

	dgn_sock_close( cli1 );
	dgn_sock_close( cli2 );

	return 0;
}

